(function($) {

	function _isEmpty(value) {
		return value == null || value == "";
	}

	function _toArray(obj) {
		return $.isArray(obj) ? obj : [obj];
	}

	function _toError(err, label, args) {
		err = err.replace(/{\*}/g, label);
		for(var i=0; i<args.length; i++) {
			var regex = new RegExp("\\{"+i+"\\}", "g");
			err = err.replace(regex, args[i]);
		}
		return err;
	}

	$.extend({

		validators : {
			
			required : {
				error:"{*}必须填写.",
				validate:function(args) {
					var value = $(this).val();
					return !args[0] || !_isEmpty(value);
				}
			},
			number : {
				error:"{*}必须是数字.",
				validate:function(args) {
					var value = $(this).val();
					return !args[0] || _isEmpty(value) || !new RegExp(/[^0-9]/g).test(value);
				}
			},
			max : {
				error:"{*}长度不能大于{0}.",
				validate:function(args) {
					var value = $(this).val();
					var max = args[0];
					return _isEmpty(value) || value.length <= max;
				}
			},
			min : {
				error:"{*}长度不能小于{0}.",
				validate:function(args) {
					var value = $(this).val();
					var min = args[0];
					return _isEmpty(value) || value.length >= min;
				}
			},
			must : {
				error:"{*}长度必须是{0}.",
				validate:function(args) {
					var value = $(this).val();
					var len = args[0];
					return _isEmpty(value) || value.length >= len;
				}
			},
			letters : {
				error:"{*}必须是字母.",
				validate:function(args) {
					var value = $(this).val();
					return !args[0] || _isEmpty(value) || !new RegExp(/[^a-zA-Z]/g).test(value);
				}
			},
			decimal : {
				error:"{*}必须是小数！（例如：123.{1}）.",
				validate:function(args) {
					var value = $(this).val();
					var count = parseInt(args[0]);
					var dot = "";
					for(var i=0; i<count; i++) {
						dot += "0";
					}
					var isSuccess = true;
					if(!_isEmpty(value)) {
						isSuccess = !new RegExp(/[^0-9.]/g).test(value);
						if(isSuccess) {
							$(this).val(parseFloat(value).toFixed(count));
						} else {
							args[1] = dot;
						}
					}
					return isSuccess;
				}
			},
			chars : {
				error:"{*}只能是字母和数字.",
				validate:function(args) {
					var value = $(this).val();
					return !args[0] || _isEmpty(value) || !new RegExp(/[^a-zA-Z0-9]/g).test(value);
				}
			},
			email : {
				error:"{*}格式不正确，不是E-Mail地址.",
				validate:function(args) {
					var value = $(this).val();
					var pattern = /^[a-zA-Z0-9_\-]{1,}@[a-zA-Z0-9_\-]{1,}\.[a-zA-Z0-9_\-.]{1,}$/;
					return !args[0] || _isEmpty(value) || pattern.exec(value);
				}
			},
			mustbe : {
				error:"{*}必须是{0}.",
				validate:function(args) {
					var value = $(this).val();
					return _isEmpty(value) || args[0] == value;
				}
			},
			telphone : {
				error:"{*}格式不正确，例如：0431-8888888.",
				validate:function(args) {
					var value = $(this).val();
					var regex = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/; 
					return !args[0] || _isEmpty(value) || regex.test(value);
				}
			},
			mobile : {
				error:"{*}格式不正确，例如：13500000000.",
				validate:function(args) {
					var value = $(this).val();
					var regex = /^0*(13|15|18)\d{9}$/; 
					return !args[0] || _isEmpty(value) || regex.test(value);
				}
			},
			idcard : {
				error:"{*}格式不正确.",
				validate:function(args) {
					var value = $(this).val();
					//身份证正则表达式(15位) 
					var isIDCard1=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/; 
					//身份证正则表达式(18位) 
					var isIDCard2=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[xX])$/;
					return !args[0] || _isEmpty(value) || isIDCard1.test(value) || isIDCard2.test(value);
				}
			},
			ng : {
				error:"{*}不能大于{0}.",
				validate:function(args) {
					var value = $(this).val();
					return _isEmpty(value) || parseFloat(value) <= args[0];
				}
			},
			nl : {
				error:"{*}不能小于{0}.",
				validate:function(args) {
					var value = $(this).val();
					return _isEmpty(value) || parseFloat(value) >= args[0];
				}
			},
			gt : {
				error:"{*}必须大于{0}.",
				validate:function(args) {
					var value = $(this).val();
					return _isEmpty(value) || parseFloat(value) > args[0];
				}
			},
			lt : {
				error:"{*}必须小于{0}.",
				validate:function(args) {
					var value = $(this).val();
					return _isEmpty(value) || parseFloat(value) < args[0];
				}
			},
			ajax : {
				error:"{*}服务器校验失败.",
				validate:function(args) {
					var value = $(this).val();
					var obj = args[0];
					var data = {};
					if(typeof(obj.extraParams) == "object") {
						$.extend(data, obj.extraParams);
					}
					data[obj.name] = value;
					var flag = false;
					//
					$.ajax({
						type : "POST",
						url : obj.link,
						data : data,
						dataType : "json",
						async : false,
						success : function(resultdata) {
							flag = resultdata;
						}
					});
					return flag;
				}
			}
		},
		//校验结果处理发放，请重写
		validateResult : function(isValidate, fields, passes, errors) {
			if(!isValidate) {
				errors[0].field.focus();
				alert(errors[0].error);
			}
		}

	});

	$.fn.extend({
		validate:function() {
			var errors = [];
			var passes = [];
			var fields = [];
			if($(this).attr("valid")) {
				fields = $([this]);
			} else {
				fields = $(this).find("[valid]");
			}
			fields.each(function() {
				var me = this;
				var valid = eval("({" + $(this).attr("valid") + "})");
				var errs = $(this).attr("errors");
				var label = $(this).attr("label");
				errs = errs ? errs : "";
				label = label ? label : "";
				errs = eval("({" + errs + "})");
				var isValid = true;
				for(name in valid) {
					var args = _toArray(valid[name]);
					var validator = $.validators[name];
					if(validator) {
						if(!validator.validate.call(me, args)) {
							var err = errs[name];
							if(!err) {
								err = validator.error;
							}
							err = _toError(err, label, args);
							errors.push({
								field:me,
								error:err
							});
							isValid = false;
							break;
						}
					}
				}
				if(isValid) {
					passes.push(me);
				}
			});
			var isValid = errors.length == 0;
			$.validateResult(isValid, fields, passes, errors);
			return isValid;
		}
	});

})(jQuery);